package org.iskycode.jeesky.sys.security;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.iskycode.jeesky.adm.entity.Permission;
import org.iskycode.jeesky.adm.entity.Role;
import org.iskycode.jeesky.adm.entity.User;
import org.iskycode.jeesky.adm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author phoenix
 *
 *         安全组件，整合shiro
 */
@Component
public class UserRealm extends AuthorizingRealm {
	@Autowired
	UserService userService;

	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String username = (String) principals.getPrimaryPrincipal();
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		// 根据用户名查询当前用户拥有的角色
		List<Role> roles = userService.findRolesByName(username);
		Set<String> roleNames = new HashSet<String>();
		for (Role role : roles) {
			roleNames.add(role.getName());
		}
		// 将角色名称提供给info
		authorizationInfo.setRoles(roleNames);
		// 根据用户名查询当前用户权限
		List<Permission> permissions = userService.findPermissionsByName(username);
		Set<String> permissionNames = new HashSet<String>();
		for (Permission permission : permissions) {
			permissionNames.add(permission.getName());
		}
		// 将权限名称提供给info
		authorizationInfo.setStringPermissions(permissionNames);

		return authorizationInfo;
	}

	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username = (String) token.getPrincipal();
		User user = userService.findUserByName(username);
		if (user == null) {
			// 用户名不存在抛出异常
			throw new UnknownAccountException();
		}

		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getName(), user.getPassword(),
				ByteSource.Util.bytes(user.getCredentialsSalt()), getName());
		return authenticationInfo;
	}
}
